package edu.pku.sei.modeler.uml.commands.compositestructure;

import edu.pku.sei.modeler.model.core.MetaModelElement;
import edu.pku.sei.modeler.model.structure.MetaLink;
import edu.pku.sei.modeler.model.structure.MetaNode;
import edu.pku.sei.modeler.model.uml.Collaborations.Collaboration;
import edu.pku.sei.modeler.model.uml.Collaborations.CollaborationUse;
import edu.pku.sei.modeler.model.uml.Dependencies.Dependency;
import edu.pku.sei.modeler.model.uml.Interfaces.Interface;
import edu.pku.sei.modeler.model.uml.InternalStructures.Connector;
import edu.pku.sei.modeler.model.uml.Kernel.Association;
import edu.pku.sei.modeler.model.uml.Kernel.Comment;
import edu.pku.sei.modeler.model.uml.Ports.Port;
import edu.pku.sei.modeler.model.uml.StructuredClasses.StructuredClass;
import edu.pku.sei.modeler.uml.commands.UMLAssociationCreateCommand;
import edu.pku.sei.modeler.uml.commands.UMLCommentLinkCreateCommand;
import edu.pku.sei.modeler.uml.commands.UMLConnectionCreateCommand;
import edu.pku.sei.modeler.uml.commands.UMLConnectionCreateCommandFactory;
import edu.pku.sei.modeler.uml.commands.component.CreateDelegationCommand;
import edu.pku.sei.modeler.uml.commands.umlclass.UMLDependencyCreateCommand;

public class CompositeStructureDiagramConnectionCreateFactory extends UMLConnectionCreateCommandFactory{

	public static final CompositeStructureDiagramConnectionCreateFactory INSTANCE = new CompositeStructureDiagramConnectionCreateFactory();
	private CompositeStructureDiagramConnectionCreateFactory(){
		
	}
	
	@Override
	public UMLConnectionCreateCommand createCommand(MetaLink link,
			MetaNode source) {
		UMLConnectionCreateCommand cmd = new UMLConnectionCreateCommand(link, source);
		MetaModelElement linkModel = link.getModelElement();
		MetaModelElement sourceModel = source.getModelElement();
		
		if (sourceModel instanceof Port) {
			if (linkModel instanceof Dependency) {
				cmd.setModelCmd(new UMLDependencyCreateCommand(link.getModelElement(), source.getModelElement()));
			} else if (linkModel instanceof Connector) {
				cmd.setModelCmd(new CreateDelegationCommand(link.getModelElement(), source.getModelElement()));	
			}
		} else if (sourceModel instanceof StructuredClass) {
			if (linkModel instanceof Association) {
				cmd.setModelCmd(new UMLAssociationCreateCommand(linkModel, sourceModel));
			}
		} else if (sourceModel instanceof Collaboration) {
			if (linkModel instanceof Association) {
				cmd.setModelCmd(new UMLAssociationCreateCommand(linkModel, sourceModel));
			}
		}
		else if (sourceModel instanceof CollaborationUse) {
			if (linkModel instanceof Dependency) {
				cmd.setModelCmd(new RoleBindingCreateCommand(linkModel, sourceModel));
			}
		} else if (sourceModel instanceof Comment) {
			if (linkModel instanceof Dependency) {
				cmd.setModelCmd(new UMLCommentLinkCreateCommand(link.getModelElement(), source.getModelElement()));
			}
		}
		if (cmd.getModelCmd() == null)
			return null;
		else 
			return cmd;
	}
	
	@Override
	public UMLConnectionCreateCommand completeCommand(UMLConnectionCreateCommand command, MetaNode target) {
		MetaModelElement linkModel = command.getLink().getModelElement();
		MetaModelElement targetModel = target.getModelElement();
		
		if (targetModel instanceof Port) {
			if (linkModel instanceof Dependency
					|| linkModel instanceof Connector) {
				command.setTarget(target);
			} 
		} else if (targetModel instanceof StructuredClass) {
			if (linkModel instanceof Association
					|| linkModel instanceof Dependency) {
				command.setTarget(target);
			}
		} else if (targetModel instanceof Collaboration) {
			if (linkModel instanceof Association
					|| linkModel instanceof Dependency) {
				command.setTarget(target);
			}
		} else if (targetModel instanceof Comment) {
			if (linkModel instanceof Dependency) {
				command.setTarget(target);
			}
		} else if (targetModel instanceof Interface) {
			if (linkModel instanceof Dependency) {
				command.setTarget(target);
			}
		} else if (targetModel instanceof CollaborationUse) {
			if (linkModel instanceof Dependency) {
				command.setTarget(target);
			}
		}
		
		if (command.getTarget() == target)
			return command;
		else 
			return null;
	}
}
